package com.qfedu.controller;

import com.alibaba.fastjson.JSONObject;
import com.qfedu.common.core.annotation.NoLogin;
import com.qfedu.common.core.common.R;
import com.qfedu.common.core.entity.LocationRecord;
import com.qfedu.service.AmapService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.Date;

/**
 * 高德地图定位服务控制器
 * 提供IP定位、逆地理编码、地理编码三大核心功能
 */
@RestController
@RequestMapping("/api/location")
public class LocationController {

    @Autowired
    private AmapService amapService; // 高德地图服务接口

    /**
     * IP定位接口
     * @param ip 需要定位的IP地址（如8.8.8.8）
     * @return 标准化响应R<JSONObject>，包含定位结果或错误信息
     */
    @GetMapping("/ip")
    @NoLogin
    public R locateByIp(@RequestParam String ip) {
        // 调用高德IP定位服务
        JSONObject result = amapService.ipLocation(ip);

        // 校验高德API返回状态码（1=成功）
        if (result != null && "1".equals(result.getString("status"))) {
            saveLocationRecord(ip, result); // 持久化定位记录
            return R.ok(result); // 返回成功响应
        }
        // 失败时返回错误信息（优先使用高德返回的info字段）
        return R.fail(result != null ? result.getString("info") : "IP定位服务不可用");
    }

    /**
     * 逆地理编码接口（坐标→地址）
     * @param longitude 经度（如116.404）
     * @param latitude 纬度（如39.915）
     * @return 包含地址信息的标准化响应
     */
    @GetMapping("/regeo")
    @NoLogin
    public R regeo(
            @RequestParam Double longitude,
            @RequestParam Double latitude) {
        JSONObject result = amapService.regeoLocation(longitude, latitude);
        if (result != null && "1".equals(result.getString("status"))) {
            saveLocationRecord(null, longitude, latitude, result); // IP传null
            return R.ok(result);
        }
        return R.fail(result != null ? result.getString("info") : "逆地理编码服务不可用");
    }

    /**
     * 地理编码接口（地址→坐标）
     * @param address 结构化地址（如"北京市海淀区中关村大街1号"）
     * @return 包含经纬度的标准化响应
     */
    @GetMapping("/geo")
    @NoLogin
    public R geo(@RequestParam String address) {
        JSONObject result = amapService.geoLocation(address);
        if (result != null && "1".equals(result.getString("status"))) {
            return R.ok(result); // 地理编码不保存记录
        }
        return R.fail(result != null ? result.getString("info") : "地理编码服务不可用");
    }

    // 内部工具方法

    /**
     * 从IP定位结果提取经纬度并保存记录
     * @param ip IP地址
     * @param result 高德API返回的完整结果
     */
    private void saveLocationRecord(String ip, JSONObject result) {
        JSONObject locationObj = result.getJSONObject("location");
        if (locationObj != null) {
            saveLocationRecord(
                    ip,
                    locationObj.getDouble("lng"), // 经度字段
                    locationObj.getDouble("lat"), // 纬度字段
                    result
            );
        }
    }

    /**
     * 保存定位记录到数据库（核心方法）
     * @param ip 可能为null（当来源是逆地理编码时）
     * @param longitude 经度（必填）
     * @param latitude 纬度（必填）
     * @param result 高德API原始结果（用于提取地址信息）
     */
    private void saveLocationRecord(
            String ip,
            Double longitude,
            Double latitude,
            JSONObject result) {
        if (result == null) return;

        // 1. 构建定位记录实体
        LocationRecord record = new LocationRecord();
        record.setIp(ip); // IP可能为null
        record.setLongitude(longitude);
        record.setLatitude(latitude);

        // 2. 提取格式化地址（如"北京市海淀区中关村大街1号"）
        String formattedAddress = result.getString("formatted_address");
        record.setAddress(formattedAddress);
        record.setFormattedAddress(formattedAddress);

        // 3. 提取结构化地址组件（省、市、区等）
        JSONObject addressComponent = result.getJSONObject("addressComponent");
        if (addressComponent != null) {
            record.setProvince(addressComponent.getString("province"));
            record.setCity(addressComponent.getString("city"));
            // 可扩展：district（区）、street（街道）等字段
        }

        // 4. 设置时间戳并保存
        record.setCreateTime(new Date());
        amapService.saveLocationRecord(record); // 调用MyBatis-Plus持久化
    }
}